package com.jinhua.usercenter.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinhua.usercenter.common.BusinessException;
import com.jinhua.usercenter.common.ErrorCode;
import com.jinhua.usercenter.common.Validator;
import com.jinhua.usercenter.contant.UserContant;
import com.jinhua.usercenter.mapper.UserMapper;
import com.jinhua.usercenter.model.User;
import com.jinhua.usercenter.model.VO.UserVO;
import com.jinhua.usercenter.service.UserService;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
* @author 20289
* @description 针对表【j_user(用户)】的数据库操作Service实现
* @createDate 2024-08-29 17:40:52
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{



    @Override
    public long registUser(String username,
                           String userAccount,
                           String password,
                           String checkPassword,
                           String phone,
                           String email,
                           String  avatarUrl,
                           Integer gender) {

//        2、对参数进行校验

//        用户名称 用户账号 头像url 密码 检查密码全不能为空
        if(StrUtil.hasBlank(username, userAccount, /*avatarUrl,*/ password,checkPassword)){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }


        //todo 细化返回错误信息

        //        用户名称长度
        if (username.length() < 4 || username.length() > 12){
            throw new BusinessException(400, "用户名长度不符合");
        }


//        检查用户账号是否合法
        String s = Validator.REGEX_USERACCOUNT;
        Matcher matcher1 = Pattern.compile(s).matcher(userAccount);
        if (!matcher1.find()){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }



//        检查性别是否符合规则
        if(gender != 0 && gender != 1){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }

//      如果手机号非空则校验
        if (StrUtil.isNotBlank(phone)){
            String validPhone = Validator.REGEX_MOBILE;
            boolean matches = Pattern.matches(validPhone, phone);
            if (!matches){
                throw new BusinessException(ErrorCode.PARAM_ERROR);
            }
        }


//      如果邮箱非空则校验
        if (StrUtil.isNotBlank(email)){
            boolean matches = Pattern.matches(Validator.REGEX_EMAIL, email);
            if (!matches){
                throw new BusinessException(ErrorCode.PARAM_ERROR);
            }
        }

//        密码校验
        boolean matches = Pattern.matches(Validator.REGEX_PASSWORD, password);
        if (!matches){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }

        if (!password.equals(checkPassword)){
            throw new BusinessException(400, "两次密码不同");
        }

        //        用户账号不能重复  放在最后 可以减少查询数据库的次数
        if (userAccountExist(userAccount) > 0){
            throw new BusinessException(400, "账户重复");
        }

//        3.密码加密
        String s1 = passwordDigest(password);

        //写入数据库
        User user = new User();
        user.setUsername(username);
        user.setUserAccount(userAccount);
        user.setPhone(phone);
        user.setEmail(email);
        user.setAvatarUrl(avatarUrl);
        user.setPassword(s1);
        user.setGender(gender);


        boolean save = this.save(user);
        if (!save){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }


        return user.getId();
    }

    @Override
    public UserVO doLogin(String userAccount, String password, HttpServletRequest request) {


        //查询参数是否为空
        if (StrUtil.hasBlank(userAccount,password)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }

        //        检查用户账号是否合法
        String s = Validator.REGEX_USERACCOUNT;
        Matcher matcher1 = Pattern.compile(s).matcher(userAccount);
        if (!matcher1.find()){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        //        密码校验
        boolean matches = Pattern.matches(Validator.REGEX_PASSWORD, password);
        if (!matches){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }

//        查询加密后的密码
        String s1 = passwordDigest(password);


//        1 查询账号密码是否正确
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserAccount,userAccount);
        User loginUser = this.getOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserAccount, userAccount)
                .eq(User::getPassword, s1));
        if (loginUser == null){
            throw new BusinessException(400, "账户不存在或者密码错误");
        }

//        2 记录用户登陆状态
        request.getSession().setAttribute(UserContant.USER_LOGIN_STATE,loginUser);

//        3 返回脱敏用户数据
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(loginUser,userVO);

        return userVO;
    }

    @Override
    public User getLoginUser(HttpServletRequest request){
        return (User)request.getSession().getAttribute(UserContant.USER_LOGIN_STATE);
    }

    @Override
    public UserVO getUserVO(User user) {
        if (user == null){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user,userVO);
        return userVO;
    }

    @Override
    public List<UserVO> getListUserVO(List<User> userList) {
        if (userList == null || userList.size() == 0){
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        return userList.stream().map(this::getUserVO).collect(Collectors.toList());
    }

    @Override
    public boolean authCheck(HttpServletRequest request){
        User loginUser = getLoginUser(request);
        if (loginUser == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN);

        }
        if (!loginUser.getUserRole().equals(UserContant.ADMIN_ROLE)){
            throw new BusinessException(ErrorCode.NO_AUTH);

        }
        return true;

    }



    private static String passwordDigest(String password){
        return SecureUtil.md5(UserContant.SALT + password);
    }

    private long userAccountExist(String userAccount){
        return this.count(new LambdaQueryWrapper<User>().eq(User::getUserAccount,userAccount));
    }

 

}




